import socket
import threading
import tkinter as tk
from tkinter import scrolledtext, messagebox

class ClipboardServer:
    def __init__(self, master):
        self.master = master
        self.master.title("给点知识-网络粘贴板服务端")

        # 输入框以指定 IP 和端口
        self.ip_label = tk.Label(master, text="服务器 IP 地址:", font=("Arial", 12))
        self.ip_label.pack(pady=5)
        self.ip_entry = tk.Entry(master, width=20)
        self.ip_entry.pack(pady=5)
        self.ip_entry.insert(0, "0.0.0.0")  # 默认 IP

        self.port_label = tk.Label(master, text="服务器 端口:", font=("Arial", 12))
        self.port_label.pack(pady=5)
        self.port_entry = tk.Entry(master, width=20)
        self.port_entry.pack(pady=5)
        self.port_entry.insert(0, "9999")  # 默认端口
        hostname = socket.gethostname()
        local_ip = socket.gethostbyname(hostname)
        # 启动服务器按钮
        self.start_button = tk.Button(master, text="启动服务器(IP:%s)" % local_ip, command=self.start_server)
        self.start_button.pack(pady=10)

        # 文本框显示当前连接的消息
        self.text_area = scrolledtext.ScrolledText(master, wrap=tk.WORD, width=50, height=20)
        self.text_area.pack(pady=10)

        self.clients = []
        self.server_socket = None

    def start_server(self):
        ip = self.ip_entry.get()
        try:
            port = int(self.port_entry.get())
            if not (1024 <= port <= 65535):
                raise ValueError("端口必须在 1024 到 65535 之间")
        except ValueError as e:
            messagebox.showerror("错误", f"无效的端口: {e}")
            return

        # 创建服务器 socket
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            self.server_socket.bind((ip, port))
            self.server_socket.listen(5)
            self.text_area.insert(tk.END, f"服务器启动，绑定地址: {ip}, 端口: {port}\n")
            threading.Thread(target=self.accept_clients, daemon=True).start()
        except Exception as e:
            messagebox.showerror("错误", f"无法启动服务器: {e}")

    def accept_clients(self):
        while True:
            client_socket, addr = self.server_socket.accept()
            self.clients.append(client_socket)
            self.text_area.insert(tk.END, f"接受连接: {addr}\n")
            threading.Thread(target=self.handle_client, args=(client_socket,), daemon=True).start()

    def handle_client(self, client_socket):
        while True:
            try:
                message = client_socket.recv(1024).decode('utf-8')
                if message:
                    self.text_area.insert(tk.END, f"收到: {message}\n")
                    self.broadcast(message)
                else:
                    break
            except ConnectionResetError:
                break

        client_socket.close()
        self.clients.remove(client_socket)

    def broadcast(self, message):
        for client in self.clients:
            try:
                client.send(message.encode('utf-8'))
            except Exception:
                client.close()
                self.clients.remove(client)

if __name__ == "__main__":
    root = tk.Tk()
    server = ClipboardServer(root)
    root.mainloop()